#include "snakegame.h"


SnakeGame::SnakeGame()
{
    this->resize(800,800);
    /* srand */
    qsrand(QTime::currentTime().msec());
    /* direction */
    dire = D_RIGHT;
    /* step size */
    footLen = 40;
    /* the max length of snake */
    Maxlen = footLen * 20;
    /* snake */
    snake.push_back(getFood());
    /* food of snake , the type is same to the snake's */
    food = getFood();

    sec = 100;

    /* create a timer to emit an signal to invoke funtion named snakeMove per Interval*/
    timer = new QTimer(this);
    timer->setInterval(sec);
    timer->start();
    /* create an relationship bewteen timer and snake's moving */
    QObject::connect(timer,SIGNAL(timeout()),this,SLOT(snakeMove()));
}

SnakeGame::~SnakeGame()
{
}

/* create the food in the dialog */
QLabel* SnakeGame::getFood()
{
    food = new QLabel(this);
    food->resize(footLen,footLen);
    food->setAutoFillBackground(true);
    food->setPalette(QPalette(QColor(qrand()%256,qrand()%256,qrand()%256)));

    int x = this->width() - footLen;
    int y = this->height() - footLen;

    /* meets three requirements
    1. create randomly
    2. not cross the border
    3. an integral multiple of footLen
    */
    food->move((qrand()%x/footLen)*footLen,(qrand()%y/footLen)*footLen);
    food->show();
    return food;
}


/* key event */
void SnakeGame::keyPressEvent(QKeyEvent *e)
{

    if(e->key() == Qt::Key_Up && dire != D_DOWN)
    {
        dire = D_UP;
    }
    if(e->key() == Qt::Key_Down && dire != D_UP)
    {
        dire = D_DOWN;
    }
    if(e->key() == Qt::Key_Left && dire != D_RIGHT)
    {
        dire = D_LEFT;
    }
    if(e->key() == Qt::Key_Right && dire != D_LEFT)
    {
        dire = D_RIGHT;
    }
}


/* snake movement */
void SnakeGame::snakeMove()
{
    /* head of snake */
    int sx = snake[0]->x();
    int sy = snake[0]->y();

    /* justify if position of head of snake equals postion of the food .
    if yes , snake eats the food and sys creates a new food in the Dialog.
    */
    if(sx == food->x() && sy == food->y())
    {
        snake.push_back(food);
        food = getFood();
    }

    for(int i = snake.size() - 1 ; i > 0 ; --i)
    {
        snake[i]->move(snake[i-1]->x(),snake[i-1]->y());
    }

    /*
    for(int i = 1 ; i < snake.size() ; ++i)
    {
        //qDebug("snake[0]->x() = %d , snake[0]->y() = %d",snake[0]->x() , snake[0]->y());
        qDebug("snake[%d]->x() = %d , snake[%d]->y() = %d",i,snake[i]->x(),i , snake[i]->y());
    }
    */

    /* justify whether snake crosses the edge of Dialog*/
    if(sx <0 || sy < 0 || sx > this->width() || sy > this->height())
    {
        QMessageBox msg(this);
        msg.setText("Game Over");
        msg.exec();
        this->close();
    }

    if(snake.size() > 4)
    {
        for(int i = 3 ; i < snake.size() ; ++i)
        {
            if(sx == snake[i]->x() && sy == snake[i]->y())
            {
                QMessageBox msg(this);
                msg.setText("Game Over");
                msg.exec();
                this->close();
            }
        }
    }


    switch(dire)
    {
        case D_UP:
            sy -= footLen;
        break;
        case D_DOWN:
            sy += footLen;
        break;
        case D_LEFT:
            sx -= footLen;
        break;
        case D_RIGHT:
            sx += footLen;
        break;
    }
    snake[0]->move(sx,sy);
}
